package com.syyo.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.syyo.common.constant.ProductContant;
import com.syyo.common.domain.ResultVo;
import com.syyo.common.enums.ResultEnum;
import com.syyo.common.exception.SysException;
import com.syyo.common.to.SkuReductionTo;
import com.syyo.common.to.SpuBoundTo;
import com.syyo.common.to.es.SkuEsModel;
import com.syyo.common.utils.MyListUtils;
import com.syyo.common.vo.SkuHasStockVo;
import com.syyo.gulimall.product.domain.entity.*;
import com.syyo.gulimall.product.domain.req.*;
import com.syyo.gulimall.product.feign.CouponFeign;
import com.syyo.gulimall.product.feign.SearchFeign;
import com.syyo.gulimall.product.feign.WareFeign;
import com.syyo.gulimall.product.mapper.*;
import com.syyo.gulimall.product.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * spu信息
 *
 * @author syyo
 * @email syyo@gmail.com
 * @date 2021-01-20 09:32:12
 */
@Slf4j
@Service
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoMapper, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SpuInfoMapper spuInfoMapper;

    @Autowired
    private SpuInfoDescMapper spuInfoDescMapper;

    @Autowired
    private SpuImagesService spuImagesService;

    @Autowired
    private ProductAttrValueService productAttrValueService;

    @Autowired
    private ProductAttrValueMapper productAttrValueMapper;

    @Autowired
    private AttrMapper attrMapper;

    @Autowired
    private SkuInfoMapper skuInfoMapper;

    @Autowired
    private SkuImagesService skuImagesService;

    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    private CouponFeign couponFeign;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private WareFeign wareFeign;

    @Autowired
    private SearchFeign searchFeign;

    /**
     * 新增
     */
    @Override
    @Transactional
    public int add(spuReq req) {

        // 1.保存基本信息 pms_spu_info
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        Date date = new Date();
        BeanUtils.copyProperties(req, spuInfoEntity);
        spuInfoEntity.setCreateTime(date);
        spuInfoEntity.setUpdateTime(date);
        spuInfoMapper.insert(spuInfoEntity);
        Long spuId = spuInfoEntity.getId();

        // 2.保存spu的描述信息 pms_spu_info_desc

        List<String> decript = req.getDecript();
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        spuInfoDescEntity.setSpuId(spuId);
        spuInfoDescEntity.setDecript(String.join(",", decript));
        spuInfoDescMapper.insert(spuInfoDescEntity);

        // 3.保存图片集 pms_spu_images
        List<String> images = req.getImages();
        if (MyListUtils.isNotEmpty(images)) {
            List<SpuImagesEntity> collect = images.stream().map(img -> {
                SpuImagesEntity spuImagesEntity = new SpuImagesEntity();
                spuImagesEntity.setSpuId(spuId);
                spuImagesEntity.setImgUrl(img);
                return spuImagesEntity;
            }).filter(item -> {
                // 返回fale会被删掉
                return !StringUtils.isEmpty(item.getImgUrl());
            }).collect(Collectors.toList());
            spuImagesService.saveBatch(collect);
        }

        // 4.保存spu的规格参数 pms_product_attr_value
        List<BaseAttrs> baseAttrs = req.getBaseAttrs();
        if (MyListUtils.isNotEmpty(baseAttrs)) {
            List<ProductAttrValueEntity> collect = baseAttrs.stream().map(attr -> {
                ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
                productAttrValueEntity.setAttrId(attr.getAttrId());
                AttrEntity attrEntity = attrMapper.selectById(attr.getAttrId());
                productAttrValueEntity.setAttrName(attrEntity.getAttrName());
                productAttrValueEntity.setAttrValue(attr.getAttrValues());
                productAttrValueEntity.setQuickShow(attr.getShowDesc());
                productAttrValueEntity.setSpuId(spuId);
                return productAttrValueEntity;
            }).collect(Collectors.toList());
            productAttrValueService.saveBatch(collect);
        }

        // 5.保存spu的积分信息 sms->sms_spu_bounds
        Bounds bounds = req.getBounds();
        SpuBoundTo spuBoundTo = new SpuBoundTo();
        BeanUtils.copyProperties(bounds, spuBoundTo);
        spuBoundTo.setSpuId(spuId);
        ResultVo resultVo1 = couponFeign.saveSpuBounds(spuBoundTo);
        if (resultVo1.getCode() != 20000) {
            log.error("远程添加积分信息失败，skuId：{}", spuId);
        }


        // 6.保存当前spu对应的sku信息
        List<Skus> skus = req.getSkus();
        if (MyListUtils.isNotEmpty(skus)) {
            for (Skus sku : skus) {
                List<Images> skuImages = sku.getImages();

                String defaultImg = "";
                for (Images skuImage : skuImages) {
                    if (skuImage.getDefaultImg() == 1) {
                        defaultImg = skuImage.getImgUrl();
                    }
                }
                // 6.1 sku的基本信息 pms_sku_info
                SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
                BeanUtils.copyProperties(sku, skuInfoEntity);
                skuInfoEntity.setBrandId(req.getBrandId());
                skuInfoEntity.setCatalogId(req.getCatalogId());
                skuInfoEntity.setSaleCount(0L);
                skuInfoEntity.setSpuId(spuInfoEntity.getId());
                skuInfoEntity.setSkuDefaultImg(defaultImg);

                skuInfoMapper.insert(skuInfoEntity);
                Long skuId = skuInfoEntity.getSkuId();

                // 6.2 sku的图片信息 pms_sku_images
                List<SkuImagesEntity> skuImagesEntitys = skuImages.stream().map(img -> {
                    SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                    skuImagesEntity.setSkuId(skuId);
                    skuImagesEntity.setImgUrl(img.getImgUrl());
                    skuImagesEntity.setDefaultImg(img.getDefaultImg());
                    return skuImagesEntity;
                }).collect(Collectors.toList());
                skuImagesService.saveBatch(skuImagesEntitys);


                // 6.3 sku的销售属性 pms_sku_sale_attr_value
                List<Attr> attrs = sku.getAttr();
                List<SkuSaleAttrValueEntity> collect = attrs.stream().map(attr -> {
                    SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                    BeanUtils.copyProperties(attr, skuSaleAttrValueEntity);
                    skuSaleAttrValueEntity.setSkuId(skuId);

                    return skuSaleAttrValueEntity;

                }).collect(Collectors.toList());
                skuSaleAttrValueService.saveBatch(collect);


                if (sku.getFullCount() > 0 || sku.getFullPrice().compareTo(new BigDecimal(0)) == 1) {
                    // 6.4 sku的优惠信息 sms库->   sms_sku_ladder sms_sku_full_reduction sms_member_price
                    SkuReductionTo skuReductionTo = new SkuReductionTo();
                    BeanUtils.copyProperties(sku, skuReductionTo);
                    skuReductionTo.setSkuId(skuId);
                    ResultVo resultVo = couponFeign.saveSkuReduction(skuReductionTo);
                    if (resultVo.getCode() != 20000) {
                        log.error("远程添加优惠信息失败，skuId：{}", skuId);
                    }
                }

            }
        }


        SpuInfoEntity entity = new SpuInfoEntity();
        // 添加创建时间和更新时间
        BeanUtils.copyProperties(req, entity);
        int insert = spuInfoMapper.insert(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10001.getCode(), ResultEnum.E_10001.getMessage());
        }
        return insert;
    }

    /**
     * 删除
     */
    @Override
    @Transactional
    public int del(Integer id) {
        int insert = spuInfoMapper.deleteById(id);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10002.getCode(), ResultEnum.E_10002.getMessage());
        }
        return insert;
    }

    /**
     * 编辑
     */
    @Override
    @Transactional
    public int edit(SpuInfoReq req) {
        SpuInfoEntity entity = new SpuInfoEntity();
        // 添加更新时间
        BeanUtils.copyProperties(req, entity);
        int insert = spuInfoMapper.updateById(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10003.getCode(), ResultEnum.E_10003.getMessage());
        }
        return insert;
    }

    /**
     * 详情
     */
    @Override
    public SpuInfoEntity findOne(Integer id) {
        return spuInfoMapper.selectById(id);
    }

    /**
     * 列表
     */
    @Override
    public IPage<SpuInfoEntity> findAll(Integer pageNum, Integer pageSize, SpuInfoReq req) {

        Page<SpuInfoEntity> teacherPage = new Page<SpuInfoEntity>(pageNum, pageSize);
        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
        if (req.getBrandId() != null) {
            wrapper.eq("brand_id", req.getBrandId());
        }

        if (req.getCatalogId() != null) {
            wrapper.eq("catalog_id", req.getCatalogId());
        }

        if (req.getPublishStatus() != null) {
            wrapper.eq("publish_status", req.getPublishStatus());
        }

        return spuInfoMapper.selectPage(teacherPage, wrapper);
    }

    @Override
    public int editStatus(SpuInfoReq req) {
        SpuInfoEntity entity = new SpuInfoEntity();
        entity.setId(req.getId());
        entity.setPublishStatus(1);
        int insert = spuInfoMapper.updateById(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10003.getCode(), ResultEnum.E_10003.getMessage());
        }
        return insert;
    }

    @Transactional
    @Override
    public int spuUp(Long spuId) {
        // 组装es需要的数据
        // 1.查出当前spuid当前的信息
        List<SkuInfoEntity> skus = skuInfoMapper.selectList(new QueryWrapper<SkuInfoEntity>().eq("spu_id", spuId));
        // 2.封装信息

        List<Long> skuIdList = skus.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());


        // 查出当前sku所有可以被检索的规格属性
        List<ProductAttrValueEntity> baseAttrs = productAttrValueMapper.selectList(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));

        List<Long> attrIds = baseAttrs.stream().map(attr -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());

        List<Long> searchAttrIds = attrMapper.findSearchAttrIds(attrIds);

        HashSet<Long> idSet = new HashSet<>(searchAttrIds);

        List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> {
            return idSet.contains(item.getAttrId());
        }).map(item -> {
            SkuEsModel.Attrs attrs1 = new SkuEsModel.Attrs();
            BeanUtils.copyProperties(item, attrs1);
            return attrs1;
        }).collect(Collectors.toList());

        Map<Long, Boolean> stocMap = null;
        try {
            // 发送远程调用库存系统，查询是否有库存
            List<SkuHasStockVo> skuHasStock = wareFeign.findSkuHasStock(skuIdList);
            stocMap = skuHasStock.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));

        } catch (Exception e) {
            log.error("库存服务查询异常：原因 {}", e);
        }

        Map<Long, Boolean> finalStocMap = stocMap;
        List<SkuEsModel> esSku = skus.stream().map((sku) -> {
            SkuEsModel esModel = new SkuEsModel();
            BeanUtils.copyProperties(sku, esModel);

            esModel.setSkuPrice(sku.getPrice());
            esModel.setSkuImg(sku.getSkuDefaultImg());

            if (finalStocMap == null) {
                esModel.setHasStock(true);
            } else {
                esModel.setHasStock(finalStocMap.get(sku.getSkuId()));
            }
            // 热度评分，默认0
            esModel.setHotScore(0L);
            // 查询品牌和分类的信息
            BrandEntity brandEntity = brandMapper.selectById(esModel.getBrandId());
            esModel.setBrandName(brandEntity.getName());
            esModel.setBrandImg(brandEntity.getLogo());

            CategoryEntity categoryEntity = categoryMapper.selectById(esModel.getCatalogId());
            esModel.setCatalogName(categoryEntity.getName());

            // 添加检索属性
            esModel.setAttrs(attrsList);
            return esModel;
        }).collect(Collectors.toList());


        // 发给es保存
        ResultVo resultVo = searchFeign.productStatusUp(esSku);
        Integer code = resultVo.getCode();
        if (code == 20000) {
            // 远程调用成功
            // 修改当前spu的状态
            spuInfoMapper.updateSpuStatus(spuId, ProductContant.StatusEnum.SPU_UP.getCode());
        } else {

            // 远程调用失败
            // todo 重复调用
        }
        return 1;
    }

    @Override
    public SpuInfoEntity getSpuBySkuId(Long skuId) {
        SkuInfoEntity skuInfoEntity = skuInfoMapper.selectById(skuId);
        return spuInfoMapper.selectById(skuInfoEntity.getSpuId());
    }

}